package com.bzframework.pro.authorize.web;

import com.bzframework.pro.authorize.annotation.Authorization;
import com.bzframework.pro.authorize.captcha.CaptchaProvider;
import com.bzframework.pro.authorize.captcha.CaptchaType;
import com.bzframework.pro.authorize.constants.RedisConstants;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.*;
import org.hswebframework.web.id.IDGenerator;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.data.redis.core.ReactiveRedisOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
 * @Author bingzhong
 * @Date 2024/11/29 15:13
 * @Description
 */
@Tag(name = "获取验证码(图片类型)")
@Getter
@Setter
@RestController
@ConfigurationProperties(prefix = "captcha.image")
@RequiredArgsConstructor
public class ImageCaptchaProvider implements CaptchaProvider {

    private final ReactiveRedisOperations<String, String> redisOperations;

    private boolean enabled = true;

    private Duration ttl = Duration.ofMinutes(2);
    private int charType = Captcha.TYPE_DEFAULT;
    private int length = 4;

    @Override
    public String getType() {
        return CaptchaType.image.name();
    }

    @GetMapping("/captcha/image")
    @Operation(summary = "生成图片验证码")
    @Authorization(ignore = true)
    public Mono<CaptchaInfo> generateCaptcha(@RequestParam(defaultValue = "130")
                                             @Parameter(description = "宽度,默认130px") int width,
                                             @RequestParam(defaultValue = "40")
                                             @Parameter(description = "高度,默认40px") int height) {
        if (!enabled) {
            return Mono.empty();
        }
        SpecCaptcha captcha = new SpecCaptcha(width, height, length);
        captcha.setCharType(charType);

        String base64 = captcha.toBase64();
        String key = IDGenerator.RANDOM.generate();
        return redisOperations
                .opsForValue()
                .set(RedisConstants.getRedisKey(RedisConstants.CAPTCHA_LOGIN, key), captcha.text(), getTtl())
                .thenReturn(new CaptchaInfo(key, base64));
    }


    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class CaptchaInfo {

        private String key;

        private String base64;
    }

}
